home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Text
/
Misc
/
Smiley
/
smiley.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-02
|
6KB
|
361 lines
/*
* s m i l e y . c
*
* DaviD W. Sanderson is to blame for this.
*/
#include "smiley.h"
#include "patchlevel.h"
/*
* macros
*/
/*
* swrite() - write() a "string variable" (char *)
*/
#define swrite(fd, s) (void) write((fd), (s), strlen(s))
/*
* lwrite() - write() a "string literal" (char [])
*/
#define lwrite(fd, lit) (void) write((fd), (lit), sizeof(lit)-1)
/*
* PUTFACE() - write() a smiley and its description
*/
#define PUTFACE(fd, i) swrite((fd), faces[i].face); \
lwrite((fd), tab); \
swrite((fd), faces[i].desc); \
lwrite((fd), newline)
/*
* FD - file descriptor to which to write the output
*/
#define FD 1
/*
* declarations
*/
extern int write();
extern int strlen();
extern char *bsearch();
/*
* definitions
*/
static char ENVAR[] = "SMILEY";
static char tab[] = "\t";
static char newline[] = "\n";
/*
* facecmp() - comparison routine for using bsearch()
*/
int
facecmp(f1, f2)
struct smiley *f1;
struct smiley *f2;
{
return strcmp(f1->face, f2->face);
}
/*
* fsearch() - return index of face, or -1 on failure
*
* Note that this assumes that there will be at most one entry in
* faces[] for a particular smiley. It also assumes that faces[] is
* sorted in ascending order.
*/
int
fsearch(s)
char *s;
{
struct smiley f;
struct smiley *ans;
f.face = s;
ans = (struct smiley *) bsearch(
(char *) &f,
(char *) faces, (unsigned) nfaces, sizeof faces[0],
facecmp);
if (ans)
return ans - faces;
else
return -1;
}
/*
* explain() - look through the list of smileys for the given face.
*
* If it is found, then print out the description.
*
* The return value is zero if the face is not found, nonzero otherwise.
*/
static int
explain(s)
char *s;
{
int i;
if((i = fsearch(s)) == -1)
return 0;
PUTFACE(FD, i);
return 1;
#if 0
int found = 0;
for (i = 0; i < nfaces; i++)
{
extern int strcmp();
if (strcmp(s, faces[i].face) == 0)
{
found = 1;
PUTFACE(FD, i);
}
}
return found;
#endif
}
/*
* main() - main program
*/
main(ac, av)
int ac;
char **av;
{
extern char *optarg;
extern int optind;
extern int opterr;
char *args = "Velf";
int Vflag = 0;
int eflag = 0;
int lflag = 0;
int fflag = 0;
int errflag = 0;
int c;
/*
* process command-line options
*/
while ((c = getopt(ac, av, args)) != -1)
{
switch (c)
{
case 'V': /* version */
Vflag = 1;
break;
case 'e': /* environment */
eflag = 1;
break;
case 'l': /* list */
lflag = 1;
break;
case 'f': /* face only */
fflag = 1;
break;
case '?':
errflag = 1;
break;
}
}
if (errflag)
{
static char msg0[] = "usage: ";
static char *msg1[] =
{
" [-V] [-e] [-l] [-f] [smiley ...]\n",
"where:\t-V\tprint program version\n",
"\t-e\texplain the face in $",
(char *) 0
};
static char *msg2[] =
{
"\n",
"\t-l\tlist all the smileys\n",
"\t-f\tprint a random smiley, face only\n",
"\tsmiley\texplain the given smileys\n",
"(no args)\tprint a random smiley\n",
(char *) 0
};
char **p;
lwrite(FD, msg0);
swrite(FD, av[0]);
for (p = msg1; *p; p++)
swrite(FD, *p);
lwrite(FD, ENVAR);
for (p = msg2; *p; p++)
swrite(FD, *p);
return 1;
}
/*
* perform command-line options
*/
/*
* Vflag - print version information
*/
if (Vflag)
{
static char stat0[] = " faces, ";
static char stat1[] = " definitions\n";
char *num;
int i;
unsigned long ndefs;
extern char *ltoa();
swrite(FD, av[0]);
lwrite(FD, version);
/*
* Print counts of the smiley faces and definitions
* The definitions for a smiley are separated by
* newlines, but not terminated by newlines.
*/
num = ltoa((unsigned long)nfaces, 10);
swrite(FD, num);
lwrite(FD, stat0);
ndefs = nfaces;
for (i=0; i<nfaces; i++)
{
char *def;
for (def = faces[i].desc; *def; def++)
{
if (*def == '\n')
ndefs++;
}
}
num = ltoa(ndefs, 10);
swrite(FD, num);
lwrite(FD, stat1);
#ifdef __DATE__
#ifdef __TIME__
{
static char when0[] = "last compiled ";
static char when1[] = __TIME__;
static char when2[] = " ";
static char when3[] = __DATE__;
static char when4[] = "\n";
lwrite(FD, when0);
lwrite(FD, when1);
lwrite(FD, when2);
lwrite(FD, when3);
lwrite(FD, when4);
}
#endif
#endif
return 0;
}
/*
* eflag - explain $SMILEY
*/
if (eflag)
{
extern char *getenv();
int unknown = 1;
char *str;
if ((str = getenv(ENVAR)) != (char *)0)
{
if(explain(str) != 0)
unknown = 0;
}
else
{
static char notset[] = " not set\n";
lwrite(FD, ENVAR);
lwrite(FD, notset);
}
return unknown;
}
/*
* lflag - list smileys
*/
if (lflag)
{
int i;
for (i = 0; i < nfaces; i++)
{
PUTFACE(FD, i);
}
return 0;
}
/*
* literal smileys - try to explain them
*
* In this case the exit status is the number of smileys
* that were not found.
*/
if (optind < ac)
{
int unknown = 0;
for (; optind < ac; optind++)
{
if(!explain(av[optind]))
unknown++;
}
return unknown;
}
/*
* otherwise - generate a random smiley
*/
{
extern int rand();
extern void srand();
extern long time();
extern int getpid();
char *f;
/*
* seed with the current time + the pid. (The pid
* prevents smileys started at identical times from
* getting the same random seed)
*/
srand((unsigned) time((long *)0) + (unsigned) getpid());
f = faces[rand() % nfaces].face;
if (fflag)
{
swrite(FD, f);
lwrite(FD, newline);
}
else
{
(void) explain(f);
}
}
return 0;
}